package com.CampaignManager.client;

import java.util.List;

import com.CampaignManager.shared.PlayerDTO;
import com.CampaignManager.shared.ResourceAmountDTO;
import com.CampaignManager.shared.UnitDTO;
import com.google.gwt.core.client.GWT;
import com.google.gwt.event.dom.client.ClickEvent;
import com.google.gwt.event.dom.client.ClickHandler;
import com.google.gwt.i18n.client.DateTimeFormat;
import com.google.gwt.uibinder.client.UiBinder;
import com.google.gwt.uibinder.client.UiField;
import com.google.gwt.user.client.Window;
import com.google.gwt.user.client.rpc.AsyncCallback;
import com.google.gwt.user.client.ui.Anchor;
import com.google.gwt.user.client.ui.Button;
import com.google.gwt.user.client.ui.Composite;
import com.google.gwt.user.client.ui.FlexTable;
import com.google.gwt.user.client.ui.Widget;

public class ArmyFrom extends Composite {

	private static ArmyFromUiBinder uiBinder = GWT.create(ArmyFromUiBinder.class);

	interface ArmyFromUiBinder extends UiBinder<Widget, ArmyFrom> {
	}

	private CampaignManager mainForm = null;
	private PlayerDTO playerInfo = null;
	
	public ArmyFrom(CampaignManager manager, PlayerDTO playerInfo) {

		this.mainForm = manager;
		this.playerInfo = playerInfo;
		
		initWidget(uiBinder.createAndBindUi(this));
		
		resourceForm.RefreshTable(playerInfo);
		
		SetupUnitTable();
		for (UnitDTO u : playerInfo.getUnits()) {
			DisplayUnitRow(u);
		}
		final int row = unitTable.getRowCount();
		unitTable.getRowFormatter().addStyleName(row, "watchListHeader");
		unitTable.setText(row, 2, "Total");
		unitTable.getCellFormatter().addStyleName(row, 2, "watchListNumericColumn");
		unitTable.setText(row, 3, playerInfo.getArmySize().toString());
		unitTable.getCellFormatter().addStyleName(row, 3, "watchListNumericColumn");
	}
	
	@UiField
	FlexTable unitTable;

	@UiField
	ResourceForm resourceForm;
	
	private void SetupUnitTable() {
		
		unitTable.getCellFormatter().setWidth(0, 0, "50");
		
		unitTable.setText(0, 1, "Unit Name");
		unitTable.setText(0, 2, "Points");
		unitTable.setText(0, 3, "Current Value");
		unitTable.setText(0, 4, "Upgrade Cost");
		unitTable.setText(0, 5, "Last Paid");
		
		unitTable.getRowFormatter().addStyleName(0, "watchListHeader");
		unitTable.addStyleName("watchList");
		unitTable.getCellFormatter().addStyleName(0, 2, "watchListNumericColumn");
		unitTable.getCellFormatter().addStyleName(0, 3, "watchListNumericColumn");
	}
	public void DisplayUnitRow(final UnitDTO unit) {
		final int row = unitTable.getRowCount();
		DisplayUnitRow(unit, row);
	}
	@SuppressWarnings("deprecation")
	public void DisplayUnitRow(final UnitDTO unit, final int row) {
		
		Long pointsAway = unit.getUpgradePointValue();
		final List<ResourceAmountDTO> upgradeCost = unit.getUpgradeCost(playerInfo.getFaction());
		
		Button upgrade = new Button("Upgrade");
		upgrade.addClickHandler(new ClickHandler() {
			public void onClick(ClickEvent event) {
				UpgradeUnit(row, unit, upgradeCost);
			}
		});		
		unitTable.setWidget(row, 0, upgrade);
		
		Long pointLimit = PlayerDTO.getPointLimit(playerInfo.getLevel());
		if ((playerInfo.getArmySize() + pointsAway) > pointLimit) {
			upgrade.setEnabled(false);
			upgrade.setTitle("Army Size limit: "+pointLimit);
		}
		if (upgradeCost.size() <= 0) {
			upgrade.setEnabled(false);
			upgrade.setTitle("Already Full Strength");
		} else if (!playerInfo.canPlayerAffordThis(upgradeCost)) {
			upgrade.setEnabled(false);
			upgrade.setTitle("Can't afford This");
		}
		if (!unit.getOwnerEmail().equalsIgnoreCase(playerInfo.getEmailAddress())) {
			upgrade.setEnabled(false);
			upgrade.setTitle("not your unit?");
		}
		
		Anchor nameLink = new Anchor(unit.getName());
		nameLink.setHref("http://battlecollege.wikispaces.com/" + unit.getUnitType().getHref());
		nameLink.setTarget("_blank");
		unitTable.setWidget(row, 1, nameLink);
						
		setPointsColumn(unit, row);
		unitTable.getCellFormatter().addStyleName(row, 2, "watchListNumericColumn");
		
		if (unit.getPoints() >= unit.getUnitType().getMaxPoints() && unit.getUnitType().getMaxPoints() > 0) {
			unitTable.setText(row, 3, unit.getUnitType().getMaxPoints().toString());
		} else if (unit.getPoints() >= unit.getUnitType().getMinPoints()) {
			unitTable.setText(row, 3, unit.getUnitType().getMinPoints().toString());
		} else {
			unitTable.setText(row, 3, "0");
		}
		unitTable.getCellFormatter().addStyleName(row, 3, "watchListNumericColumn");
	
		unitTable.setText(row, 4, mainForm.CostText(upgradeCost));
		unitTable.setText(row, 5, DateTimeFormat.getShortDateFormat().format(unit.getLastPaid()));
	}
	
	private void setPointsColumn(final UnitDTO unit, final int row) {
		if (unit.getPoints() < unit.getUnitType().getMinPoints() || unit.getUnitType().getMaxPoints() == 0) {
			unitTable.setText(row, 2, unit.getPoints() + "/" + unit.getUnitType().getMinPoints().toString());
		} else {
			unitTable.setText(row, 2, unit.getPoints() + "/" + unit.getUnitType().getMaxPoints().toString());
		}
		if (unit.getPoints() >= unit.getUnitType().getMaxPoints() && unit.getUnitType().getMaxPoints() > 0) {
			unitTable.setText(row, 3, unit.getUnitType().getMaxPoints().toString());
		} else if (unit.getPoints() >= unit.getUnitType().getMinPoints()) {
			unitTable.setText(row, 3, unit.getUnitType().getMinPoints().toString());
		} else {
			unitTable.setText(row, 3, "0");
		}
	}
	
	private void UpgradeUnit(final int row, final UnitDTO unit, final List<ResourceAmountDTO> upgradeCost) {
		
		final Long pointsAway = unit.getUpgradePointValue();
				
		mainForm.campaignService.UpgradeUnit(unit, new AsyncCallback<String>() {			
			public void onFailure(Throwable error) {
				mainForm.handleError(error);
			}
			public void onSuccess(String result) {
				
				Window.alert(result);
				
				if (result.equals("Unit Upgraded")) {
					for (ResourceAmountDTO rac : upgradeCost) {
						ResourceAmountDTO playerRac = playerInfo.getResource(rac.getResource());
						playerRac.setAmount(playerRac.getAmount()-rac.getAmount());				
					}				
					unit.setPoints(unit.getPoints() + pointsAway);
					DisplayUnitRow(unit, row);
					resourceForm.RefreshTable(playerInfo);
				}
			}
		});			
	}
}
